package com.ithinkstudio.jeez.dao.impl;

import com.ithinkstudio.jeez.dao.IBaseRepository;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.query.Query;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate5.support.HibernateDaoSupport;
import org.springframework.util.Assert;

import javax.annotation.PostConstruct;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.PersistenceContext;
import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.List;

/**
 * @description: 测试HibernateDaoSupport
 * @author: fengzp
 * @create: 2020/04/15
 */
public class BaseRepository<T> extends HibernateDaoSupport implements IBaseRepository<T> {

    protected Logger LOG = LoggerFactory.getLogger(getClass());

    @PersistenceContext
    protected EntityManager entityManager;

    @Autowired
    protected EntityManagerFactory entityManagerFactory;

    /**
     * 实例化时反注入父类中的SessionFactory
     */
    @PostConstruct
    public void init() {
        Assert.notNull(entityManagerFactory, "初始化失败，没有注入EntityManagerFactory！");
        SessionFactory sessionFactory = entityManagerFactory.unwrap(SessionFactory.class);
        super.setSessionFactory(sessionFactory);
    }

    /**
     * 获取Session
     */
    protected Session getSession() {
        return entityManager.unwrap(Session.class);
    }


    /**
     * 获取泛型的类
     */
    private Class<T> clazz;
    @SuppressWarnings("unchecked")
    public Class<T> getClazz() {
        if (clazz == null) {
            clazz = (Class<T>)(((ParameterizedType)(this.getClass().getGenericSuperclass())).getActualTypeArguments()[0]);
        }
        return clazz;
    }


    /**
     * 添加
     *
     * @param model
     */
    @Override
    public void insert(T model) {
        this.getHibernateTemplate().save(model);
    }

    /**
     * 修改
     *
     * @param model
     */
    @Override
    public void update(T model) {
        this.getHibernateTemplate().update(model);
    }

    /**
     * 删除
     *
     * @param model
     */
    @Override
    public void delete(T model) {
        this.getHibernateTemplate().delete(model);
    }

    /**
     * 删除
     *
     * @param key
     */
    @Override
    public void delete(Serializable key) {
        T entity = this.getHibernateTemplate().load(getClazz(), key);
        if (null != entity) {
            this.getHibernateTemplate().delete(entity);
        }
    }

    /**
     * 根据ID查询
     *
     * @param key
     * @return
     */
    @Override
    public T findById(Serializable key) {
        //return this.getHibernateTemplate().get(getClazz(), key);
        return this.getHibernateTemplate().load(getClazz(), key);
    }

    /**
     * 根据hql查询集合
     *
     * @param hql
     * @param args
     * @return
     */
    @Override
    public List<T> list(String hql, Object[] args) {
        Query<T> query = getSession().createQuery(hql);
        if (args != null) {
            for (int i = 0; i < args.length; i++) {
                query.setParameter(i, args[i]);
            }
        }
        List<T> list = query.list();
        return list;
    }
}
